From 6d18a808414267748cf846c1f2c40dcb15a29a26 Mon Sep 17 00:00:00 2001 From: Nikolas Komonen Date: Thu, 23 May 2019 17:22:48 -0400 Subject: [PATCH] DTD Attlist symbols will show multiple ATTLIST attributes Fixes#265 Signed-off-by: Nikolas Komonen --- .../lsp4xml/services/XMLSymbolsProvider.java | 82 +++++++++++++++---- .../services/XMLDocumentSymbolsTest.java | 61 ++++++++++---- .../services/XMLSymbolInformationsTest.java | 4 +- 3 files changed, 111 insertions(+), 36 deletions(-) diff --git a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/services/XMLSymbolsProvider.java b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/services/XMLSymbolsProvider.java index 6f9c252745..2e7008e78f 100644 --- a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/services/XMLSymbolsProvider.java +++ b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/services/XMLSymbolsProvider.java @@ -27,6 +27,7 @@ import org.eclipse.lsp4xml.dom.DOMDocument; import org.eclipse.lsp4xml.dom.DOMNode; import org.eclipse.lsp4xml.dom.DTDAttlistDecl; +import org.eclipse.lsp4xml.dom.DTDDeclParameter; import org.eclipse.lsp4xml.dom.DTDElementDecl; import org.eclipse.lsp4xml.dom.DTDNotationDecl; import org.eclipse.lsp4xml.services.extensions.XMLExtensionsRegistry; @@ -85,31 +86,60 @@ private void findDocumentSymbols(DOMNode node, List symbols, Lis return; } boolean hasChildNodes = node.hasChildNodes(); - List children = symbols; - if (!nodesToIgnore.contains(node)) { - String name = nodeToName(node); - Range selectionRange = getSymbolRange(node); + List childrenSymbols = symbols; + if (nodesToIgnore == null || !nodesToIgnore.contains(node)) { + String name; + Range selectionRange; + + if (nodesToIgnore != null && node.isDTDAttListDecl()) { // attlistdecl with no elementdecl references + DTDAttlistDecl decl = (DTDAttlistDecl) node; + name = decl.getElementName(); + selectionRange = getSymbolRange(node, true); + } + else { // regular node + name = nodeToName(node); + selectionRange = getSymbolRange(node); + + } Range range = selectionRange; - children = hasChildNodes || node.isDTDElementDecl() ? new ArrayList<>() : Collections.emptyList(); - DocumentSymbol symbol = new DocumentSymbol(name, getSymbolKind(node), range, selectionRange, null, - children); - + childrenSymbols = hasChildNodes || node.isDTDElementDecl() || node.isDTDAttListDecl() ? new ArrayList<>() : Collections.emptyList(); + DocumentSymbol symbol = new DocumentSymbol(name, getSymbolKind(node), range, selectionRange, null, childrenSymbols); symbols.add(symbol); - if (node.isDTDElementDecl()) { + + if (node.isDTDElementDecl() || (nodesToIgnore != null && node.isDTDAttListDecl())) { // In the case of DTD ELEMENT we try to add in the children the DTD ATTLIST - DTDElementDecl elementDecl = (DTDElementDecl) node; - String elementName = elementDecl.getName(); - Collection attlistDecls = node.getOwnerDocument().findDTDAttrList(elementName); + Collection attlistDecls; + if(node.isDTDElementDecl()) { + DTDElementDecl elementDecl = (DTDElementDecl) node; + String elementName = elementDecl.getName(); + attlistDecls = node.getOwnerDocument().findDTDAttrList(elementName); + } + else { + attlistDecls = new ArrayList(); + attlistDecls.add(node); + } + for (DOMNode attrDecl : attlistDecls) { - findDocumentSymbols(attrDecl, children, nodesToIgnore); + findDocumentSymbols(attrDecl, childrenSymbols, null); + if(attrDecl instanceof DTDAttlistDecl) { + DTDAttlistDecl decl = (DTDAttlistDecl) attrDecl; + List otherAttributeDecls = decl.getInternalChildren(); + if(otherAttributeDecls != null) { + for (DTDAttlistDecl internalDecl : otherAttributeDecls) { + findDocumentSymbols(internalDecl, childrenSymbols, null); + } + } + } nodesToIgnore.add(attrDecl); } } + + } if (!hasChildNodes) { return; } - final List childrenOfChild = children; + final List childrenOfChild = childrenSymbols; node.getChildren().forEach(child -> { try { findDocumentSymbols(child, childrenOfChild, nodesToIgnore); @@ -145,10 +175,28 @@ private void findSymbolInformations(DOMNode node, String container, List"; XMLAssert.testDocumentSymbolsFor(dtd, "test.dtd", // ds("br", SymbolKind.Property, r(0, 0, 0, 19), r(0, 0, 0, 19), null, // - Arrays.asList(ds("%all;", SymbolKind.Key, r(1, 0, 2, 7), r(1, 0, 2, 7), null, - Collections.emptyList())))); + Arrays.asList(ds("%all;", SymbolKind.Key, r(2, 1, 2, 6), r(2, 1, 2, 6), null, Arrays.asList())))); + + } + + @Test + public void multipleAttlistValues() { + String dtd = + "\r\n" + + " \r\n" + + "\r\n" + + " \r\n" + + " \r\n" + + "\r\n"; + + XMLAssert.testDocumentSymbolsFor(dtd, "test.dtd", + ds("target", SymbolKind.Property, r(0, 0, 0, 23), r(0, 0, 0, 23), null, + Arrays.asList( + ds("tid", SymbolKind.Key, r(3, 10, 3, 13), r(3, 10, 3, 13), null, Arrays.asList()), + ds("bee", SymbolKind.Key, r(6, 10, 6, 13), r(6, 10, 6, 13), null, Arrays.asList()) + ) + ), + ds("extension-point", SymbolKind.Key, r(9, 0, 11, 29), r(9, 0, 11, 29), null, + Arrays.asList( + ds("ep", SymbolKind.Key, r(10, 10, 10, 12), r(10, 10, 10, 12), null, Arrays.asList()), + ds("ep2", SymbolKind.Key, r(11, 10, 11, 13), r(11, 10, 11, 13), null, Arrays.asList()) + ))); } @Test public void internalDTD() { - String xml = - "\r\n" + // + String xml = "\r\n" + // "\r\n" + // " \r\n" + // @@ -47,19 +76,17 @@ public void internalDTD() { XMLAssert.testDocumentSymbolsFor(xml, "test.xml", // ds("xml", SymbolKind.Property, r(0, 0, 0, 23), r(0, 0, 0, 23), null, // Collections.emptyList()), // - ds("DOCTYPE:Folks", SymbolKind.Struct, r(1, 0, 9, 3), r(1, 0, 9, 3), null, Arrays.asList( - ds("Folks", SymbolKind.Property, r(2, 1, 2, 27), r(2, 1, 2, 27), null, Collections.emptyList()), // - ds("Person", SymbolKind.Property, r(3, 1, 3, 32), r(3, 1, 3, 32), null, // - Arrays.asList( // - ds("Pin", SymbolKind.Key, r(4, 1, 4, 35), r(4, 1, 4, 35), null, - Collections.emptyList()), // - ds("Friend", SymbolKind.Key, r(5, 1, 5, 40), r(5, 1, 5, 40), null, - Collections.emptyList()), // - ds("Likes", SymbolKind.Key, r(6, 1, 6, 40), r(6, 1, 6, 40), null, - Collections.emptyList()))), // - ds("Name", SymbolKind.Property, r(7, 1, 7, 26), r(7, 1, 7, 26), null, Collections.emptyList()), // - ds("Email", SymbolKind.Property, r(8, 1, 8, 27), r(8, 1, 8, 27), null, Collections.emptyList()) // - )), // + ds("DOCTYPE:Folks", SymbolKind.Struct, r(1, 0, 9, 3), r(1, 0, 9, 3), null, + Arrays.asList( + ds("Folks", SymbolKind.Property, r(2, 1, 2, 27), r(2, 1, 2, 27), null, Collections.emptyList()), // + ds("Person", SymbolKind.Property, r(3, 1, 3, 32), r(3, 1, 3, 32), null, // + Arrays.asList( // + ds("Pin", SymbolKind.Key, r(4, 18, 4, 21), r(4, 18, 4, 21), null, Collections.emptyList()), // + ds("Friend", SymbolKind.Key, r(5, 18, 5, 24), r(5, 18, 5, 24), null, Collections.emptyList()), // + ds("Likes", SymbolKind.Key, r(6, 18, 6, 23), r(6, 18, 6, 23), null, Collections.emptyList()))), // + ds("Name", SymbolKind.Property, r(7, 1, 7, 26), r(7, 1, 7, 26), null, Collections.emptyList()), // + ds("Email", SymbolKind.Property, r(8, 1, 8, 27), r(8, 1, 8, 27), null, Collections.emptyList()) // + )), // ds("Folks", SymbolKind.Field, r(10, 0, 12, 8), r(10, 0, 12, 8), null, Collections.emptyList())); } } diff --git a/org.eclipse.lsp4xml/src/test/java/org/eclipse/lsp4xml/services/XMLSymbolInformationsTest.java b/org.eclipse.lsp4xml/src/test/java/org/eclipse/lsp4xml/services/XMLSymbolInformationsTest.java index f7aa6ea7cf..63f5c6edd9 100644 --- a/org.eclipse.lsp4xml/src/test/java/org/eclipse/lsp4xml/services/XMLSymbolInformationsTest.java +++ b/org.eclipse.lsp4xml/src/test/java/org/eclipse/lsp4xml/services/XMLSymbolInformationsTest.java @@ -205,7 +205,7 @@ public void externalDTD() { currentSymbolInfo = createSymbolInformation("br", SymbolKind.Property, currentLocation, ""); expectedSymbolInfos.add(currentSymbolInfo); - currentLocation = createLocation(testURI, 20, 40, xmlDocument); + currentLocation = createLocation(testURI, 34, 39, xmlDocument); currentSymbolInfo = createSymbolInformation("%all;", SymbolKind.Key, currentLocation, ""); expectedSymbolInfos.add(currentSymbolInfo); @@ -230,7 +230,7 @@ public void internalDTD() { currentSymbolInfo = createSymbolInformation("br", SymbolKind.Property, currentLocation, "DOCTYPE:br"); expectedSymbolInfos.add(currentSymbolInfo); - currentLocation = createLocation(testURI, 39, 60, xmlDocument); + currentLocation = createLocation(testURI, 54, 59, xmlDocument); currentSymbolInfo = createSymbolInformation("%all;", SymbolKind.Key, currentLocation, "DOCTYPE:br"); expectedSymbolInfos.add(currentSymbolInfo);