From f4d6d4ae56bbb7c7afb2d2de567f5aa86a4c6e75 Mon Sep 17 00:00:00 2001 From: angelozerr Date: Wed, 5 Dec 2018 01:15:55 +0100 Subject: [PATCH] Simplify DTD symbols + add tests (see #226) --- .../lsp4xml/services/XMLSymbolsProvider.java | 34 +- .../lsp4xml/services/XMLSymbolsTest.java | 471 ++++++++++-------- 2 files changed, 273 insertions(+), 232 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 22375941d..7469502a0 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 @@ -11,7 +11,6 @@ package org.eclipse.lsp4xml.services; import java.util.ArrayList; -import java.util.Collection; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; @@ -49,7 +48,7 @@ public List findDocumentSymbols(DOMDocument xmlDocument) { boolean isDTD = xmlDocument.isDTD(); xmlDocument.getRoots().forEach(node -> { try { - provideFileSymbolsInternal(node, "", symbols, (node.isDoctype() && isDTD), true); + provideFileSymbolsInternal(node, "", symbols, (node.isDoctype() && isDTD)); } catch (BadLocationException e) { LOGGER.log(Level.SEVERE, "XMLSymbolsProvider was given a BadLocation by a 'node' variable", e); } @@ -58,8 +57,8 @@ public List findDocumentSymbols(DOMDocument xmlDocument) { } private void provideFileSymbolsInternal(DOMNode node, String container, List symbols, - boolean ignoreNode, boolean checkSymbol) throws BadLocationException { - if (checkSymbol && !isNodeSymbol(node)) { + boolean ignoreNode) throws BadLocationException { + if (!isNodeSymbol(node)) { return; } String name = ignoreNode ? "" : nodeToName(node); @@ -75,43 +74,30 @@ private void provideFileSymbolsInternal(DOMNode node, String container, List { try { - provideFileSymbolsInternal(child, name, symbols, false, true); + provideFileSymbolsInternal(child, name, symbols, false); } catch (BadLocationException e) { LOGGER.log(Level.SEVERE, "XMLSymbolsProvider was given a BadLocation by the provided 'node' variable", e); } }); - if (node.isDTDElementDecl()) { - String elementName = node.getNodeName(); - // Display DTD attributes = node.getOwnerDocument().getDTDAttrList(elementName); - attributes.forEach(child -> { - try { - provideFileSymbolsInternal(child, elementName, symbols, false, false); - } catch (BadLocationException e) { - LOGGER.log(Level.SEVERE, - "XMLSymbolsProvider was given a BadLocation by the provided 'node' variable", e); - } - }); - - } - } private SymbolKind getSymbolKind(DOMNode node) { if (node.isProcessingInstruction() || node.isProlog()) { return SymbolKind.Property; } else if (node.isDoctype()) { - return SymbolKind.Enum; - } else if (node.isDTDElementDecl() || node.isDTDAttListDecl() || node.isDTDEntityDecl()) { - return SymbolKind.EnumMember; + return SymbolKind.Struct; + } else if (node.isDTDElementDecl() || node.isDTDEntityDecl()) { + return SymbolKind.Property; + } else if (node.isDTDAttListDecl()) { + return SymbolKind.Key; } return SymbolKind.Field; } private boolean isNodeSymbol(DOMNode node) { return node.isElement() || node.isDoctype() || node.isProcessingInstruction() || node.isProlog() - || node.isDTDElementDecl() || node.isDTDEntityDecl(); + || node.isDTDElementDecl() || node.isDTDAttListDecl() || node.isDTDEntityDecl(); } private static String nodeToName(DOMNode node) { diff --git a/org.eclipse.lsp4xml/src/test/java/org/eclipse/lsp4xml/services/XMLSymbolsTest.java b/org.eclipse.lsp4xml/src/test/java/org/eclipse/lsp4xml/services/XMLSymbolsTest.java index 4ada3f608..e5e7fc595 100644 --- a/org.eclipse.lsp4xml/src/test/java/org/eclipse/lsp4xml/services/XMLSymbolsTest.java +++ b/org.eclipse.lsp4xml/src/test/java/org/eclipse/lsp4xml/services/XMLSymbolsTest.java @@ -21,226 +21,281 @@ * XMLSymbolsTest */ public class XMLSymbolsTest { - private static final String testURI = "test:URI"; - private XMLLanguageService languageService; - private DOMDocument xmlDocument; - private List actualSymbolInfos; - private List expectedSymbolInfos; - private Location currentLocation; - private SymbolInformation currentSymbolInfo; + private static final String testURI = "test:URI"; + private XMLLanguageService languageService; + private DOMDocument xmlDocument; + private List actualSymbolInfos; + private List expectedSymbolInfos; + private Location currentLocation; + private SymbolInformation currentSymbolInfo; @Before public void initializeLanguageService() { - languageService = new XMLLanguageService(); - } - - @Test - public void testSingleSymbol() { - String xmlText = ""; - initializeTestObjects(xmlText); - - currentLocation = createLocation(testURI, 0, 19, xmlDocument); - currentSymbolInfo = createSymbolInformation("project", SymbolKind.Field, currentLocation, ""); - expectedSymbolInfos.add(currentSymbolInfo); - - assertSymbols(expectedSymbolInfos, actualSymbolInfos); - } - - @Test - public void testNestedSymbol() { - String xmlText = ""; - initializeTestObjects(xmlText); - - currentLocation = createLocation(testURI, 0, 36, xmlDocument); - currentSymbolInfo = createSymbolInformation("project", SymbolKind.Field, currentLocation, ""); - expectedSymbolInfos.add(currentSymbolInfo); - - currentLocation = createLocation(testURI, 9, 26, xmlDocument); - currentSymbolInfo = createSymbolInformation("inside", SymbolKind.Field, currentLocation, "project"); - expectedSymbolInfos.add(currentSymbolInfo); - - assertSymbols(expectedSymbolInfos, actualSymbolInfos); - } - - @Test - public void testTwoNestedSymbols() { - String xmlText = ""; - initializeTestObjects(xmlText); - - currentLocation = createLocation(testURI, 0, 21, xmlDocument); - currentSymbolInfo = createSymbolInformation("a", SymbolKind.Field, currentLocation, ""); - expectedSymbolInfos.add(currentSymbolInfo); - - currentLocation = createLocation(testURI, 3, 10, xmlDocument); - currentSymbolInfo = createSymbolInformation("b", SymbolKind.Field, currentLocation, "a"); - expectedSymbolInfos.add(currentSymbolInfo); - - currentLocation = createLocation(testURI, 10, 17, xmlDocument); - currentSymbolInfo = createSymbolInformation("c", SymbolKind.Field, currentLocation, "a"); - expectedSymbolInfos.add(currentSymbolInfo); - - assertSymbols(expectedSymbolInfos, actualSymbolInfos); - } - - @Test - public void testNestedTwice() { - String xmlText = ""; - initializeTestObjects(xmlText); - - currentLocation = createLocation(testURI, 0, 21, xmlDocument); - currentSymbolInfo = createSymbolInformation("a", SymbolKind.Field, currentLocation, ""); - expectedSymbolInfos.add(currentSymbolInfo); - - currentLocation = createLocation(testURI, 3, 17, xmlDocument); - currentSymbolInfo = createSymbolInformation("b", SymbolKind.Field, currentLocation, "a"); - expectedSymbolInfos.add(currentSymbolInfo); - - currentLocation = createLocation(testURI, 6, 13, xmlDocument); - currentSymbolInfo = createSymbolInformation("c", SymbolKind.Field, currentLocation, "b"); - expectedSymbolInfos.add(currentSymbolInfo); - - assertSymbols(expectedSymbolInfos, actualSymbolInfos); - } - - @Test - public void testSelfClosingTag() { - String xmlText = ""; - initializeTestObjects(xmlText); - - currentLocation = createLocation(testURI, 0, 4, xmlDocument); - currentSymbolInfo = createSymbolInformation("a", SymbolKind.Field, currentLocation, ""); - expectedSymbolInfos.add(currentSymbolInfo); - - assertSymbols(expectedSymbolInfos, actualSymbolInfos); - } - - @Test - public void testNestedSelfClosingTag() { - String xmlText = ""; - initializeTestObjects(xmlText); - - currentLocation = createLocation(testURI, 0, 11, xmlDocument); - currentSymbolInfo = createSymbolInformation("a", SymbolKind.Field, currentLocation, ""); - expectedSymbolInfos.add(currentSymbolInfo); - - currentLocation = createLocation(testURI, 3, 7, xmlDocument); - currentSymbolInfo = createSymbolInformation("b", SymbolKind.Field, currentLocation, "a"); - expectedSymbolInfos.add(currentSymbolInfo); - - assertSymbols(expectedSymbolInfos, actualSymbolInfos); - } - - @Test - public void testUnclosedTag() { - String xmlText = ""; - initializeTestObjects(xmlText); - - currentLocation = createLocation(testURI, 0, 3, xmlDocument); - currentSymbolInfo = createSymbolInformation("a", SymbolKind.Field, currentLocation, ""); - expectedSymbolInfos.add(currentSymbolInfo); - - assertSymbols(expectedSymbolInfos, actualSymbolInfos); - } - - @Test - public void testNestedUnclosedTag() { - String xmlText = ""; - initializeTestObjects(xmlText); - - currentLocation = createLocation(testURI, 0, 10, xmlDocument); - currentSymbolInfo = createSymbolInformation("a", SymbolKind.Field, currentLocation, ""); - expectedSymbolInfos.add(currentSymbolInfo); - - currentLocation = createLocation(testURI, 3, 6, xmlDocument); - currentSymbolInfo = createSymbolInformation("b", SymbolKind.Field, currentLocation, "a"); - expectedSymbolInfos.add(currentSymbolInfo); - - assertSymbols(expectedSymbolInfos, actualSymbolInfos); - } - - @Test - public void testAllTagsUnclosed() { - String xmlText = ""; - initializeTestObjects(xmlText); - - currentLocation = createLocation(testURI, 0, 6, xmlDocument); - currentSymbolInfo = createSymbolInformation("a", SymbolKind.Field, currentLocation, ""); - expectedSymbolInfos.add(currentSymbolInfo); - - currentLocation = createLocation(testURI, 3, 6, xmlDocument); - currentSymbolInfo = createSymbolInformation("b", SymbolKind.Field, currentLocation, "a"); - expectedSymbolInfos.add(currentSymbolInfo); - - assertSymbols(expectedSymbolInfos, actualSymbolInfos); - } - - @Test + languageService = new XMLLanguageService(); + } + + @Test + public void testSingleSymbol() { + String xmlText = ""; + initializeTestObjects(xmlText); + + currentLocation = createLocation(testURI, 0, 19, xmlDocument); + currentSymbolInfo = createSymbolInformation("project", SymbolKind.Field, currentLocation, ""); + expectedSymbolInfos.add(currentSymbolInfo); + + assertSymbols(expectedSymbolInfos, actualSymbolInfos); + } + + @Test + public void testNestedSymbol() { + String xmlText = ""; + initializeTestObjects(xmlText); + + currentLocation = createLocation(testURI, 0, 36, xmlDocument); + currentSymbolInfo = createSymbolInformation("project", SymbolKind.Field, currentLocation, ""); + expectedSymbolInfos.add(currentSymbolInfo); + + currentLocation = createLocation(testURI, 9, 26, xmlDocument); + currentSymbolInfo = createSymbolInformation("inside", SymbolKind.Field, currentLocation, "project"); + expectedSymbolInfos.add(currentSymbolInfo); + + assertSymbols(expectedSymbolInfos, actualSymbolInfos); + } + + @Test + public void testTwoNestedSymbols() { + String xmlText = ""; + initializeTestObjects(xmlText); + + currentLocation = createLocation(testURI, 0, 21, xmlDocument); + currentSymbolInfo = createSymbolInformation("a", SymbolKind.Field, currentLocation, ""); + expectedSymbolInfos.add(currentSymbolInfo); + + currentLocation = createLocation(testURI, 3, 10, xmlDocument); + currentSymbolInfo = createSymbolInformation("b", SymbolKind.Field, currentLocation, "a"); + expectedSymbolInfos.add(currentSymbolInfo); + + currentLocation = createLocation(testURI, 10, 17, xmlDocument); + currentSymbolInfo = createSymbolInformation("c", SymbolKind.Field, currentLocation, "a"); + expectedSymbolInfos.add(currentSymbolInfo); + + assertSymbols(expectedSymbolInfos, actualSymbolInfos); + } + + @Test + public void testNestedTwice() { + String xmlText = ""; + initializeTestObjects(xmlText); + + currentLocation = createLocation(testURI, 0, 21, xmlDocument); + currentSymbolInfo = createSymbolInformation("a", SymbolKind.Field, currentLocation, ""); + expectedSymbolInfos.add(currentSymbolInfo); + + currentLocation = createLocation(testURI, 3, 17, xmlDocument); + currentSymbolInfo = createSymbolInformation("b", SymbolKind.Field, currentLocation, "a"); + expectedSymbolInfos.add(currentSymbolInfo); + + currentLocation = createLocation(testURI, 6, 13, xmlDocument); + currentSymbolInfo = createSymbolInformation("c", SymbolKind.Field, currentLocation, "b"); + expectedSymbolInfos.add(currentSymbolInfo); + + assertSymbols(expectedSymbolInfos, actualSymbolInfos); + } + + @Test + public void testSelfClosingTag() { + String xmlText = ""; + initializeTestObjects(xmlText); + + currentLocation = createLocation(testURI, 0, 4, xmlDocument); + currentSymbolInfo = createSymbolInformation("a", SymbolKind.Field, currentLocation, ""); + expectedSymbolInfos.add(currentSymbolInfo); + + assertSymbols(expectedSymbolInfos, actualSymbolInfos); + } + + @Test + public void testNestedSelfClosingTag() { + String xmlText = ""; + initializeTestObjects(xmlText); + + currentLocation = createLocation(testURI, 0, 11, xmlDocument); + currentSymbolInfo = createSymbolInformation("a", SymbolKind.Field, currentLocation, ""); + expectedSymbolInfos.add(currentSymbolInfo); + + currentLocation = createLocation(testURI, 3, 7, xmlDocument); + currentSymbolInfo = createSymbolInformation("b", SymbolKind.Field, currentLocation, "a"); + expectedSymbolInfos.add(currentSymbolInfo); + + assertSymbols(expectedSymbolInfos, actualSymbolInfos); + } + + @Test + public void testUnclosedTag() { + String xmlText = ""; + initializeTestObjects(xmlText); + + currentLocation = createLocation(testURI, 0, 3, xmlDocument); + currentSymbolInfo = createSymbolInformation("a", SymbolKind.Field, currentLocation, ""); + expectedSymbolInfos.add(currentSymbolInfo); + + assertSymbols(expectedSymbolInfos, actualSymbolInfos); + } + + @Test + public void testNestedUnclosedTag() { + String xmlText = ""; + initializeTestObjects(xmlText); + + currentLocation = createLocation(testURI, 0, 10, xmlDocument); + currentSymbolInfo = createSymbolInformation("a", SymbolKind.Field, currentLocation, ""); + expectedSymbolInfos.add(currentSymbolInfo); + + currentLocation = createLocation(testURI, 3, 6, xmlDocument); + currentSymbolInfo = createSymbolInformation("b", SymbolKind.Field, currentLocation, "a"); + expectedSymbolInfos.add(currentSymbolInfo); + + assertSymbols(expectedSymbolInfos, actualSymbolInfos); + } + + @Test + public void testAllTagsUnclosed() { + String xmlText = ""; + initializeTestObjects(xmlText); + + currentLocation = createLocation(testURI, 0, 6, xmlDocument); + currentSymbolInfo = createSymbolInformation("a", SymbolKind.Field, currentLocation, ""); + expectedSymbolInfos.add(currentSymbolInfo); + + currentLocation = createLocation(testURI, 3, 6, xmlDocument); + currentSymbolInfo = createSymbolInformation("b", SymbolKind.Field, currentLocation, "a"); + expectedSymbolInfos.add(currentSymbolInfo); + + assertSymbols(expectedSymbolInfos, actualSymbolInfos); + } + + @Test public void singleEndTag() throws BadLocationException { - String xmlText = ""; - initializeTestObjects(xmlText); + String xmlText = ""; + initializeTestObjects(xmlText); + + currentLocation = createLocation(testURI, 0, 7, xmlDocument); + currentSymbolInfo = createSymbolInformation("meta", SymbolKind.Field, currentLocation, ""); + expectedSymbolInfos.add(currentSymbolInfo); - currentLocation = createLocation(testURI, 0, 7, xmlDocument); - currentSymbolInfo = createSymbolInformation("meta", SymbolKind.Field, currentLocation, ""); - expectedSymbolInfos.add(currentSymbolInfo); + assertSymbols(expectedSymbolInfos, actualSymbolInfos); - assertSymbols(expectedSymbolInfos, actualSymbolInfos); - } - - @Test + + @Test public void insideEndTag() throws BadLocationException { - //assertRename("", "newText", edits("newText", r(0, 1, 5), r(0, 15, 19))); - } - - //-------------------Tools------------------------------ - - private void initializeTestObjects(String xmlText) { - xmlDocument = DOMParser.getInstance().parse(xmlText, testURI, null); - actualSymbolInfos = languageService.findDocumentSymbols(xmlDocument); - expectedSymbolInfos = new ArrayList(); - } - - private void assertSymbols(List expectedSymbolList, List actualSymbolList) { - assertEquals(expectedSymbolList.size(), actualSymbolList.size()); - - SymbolInformation currentExpectedSymbol; - SymbolInformation currentActualSymbol; - - for(int i = 0; i < expectedSymbolList.size(); i++) { - currentExpectedSymbol = expectedSymbolList.get(i); - currentActualSymbol = actualSymbolList.get(i); - assertEquals(currentExpectedSymbol.getName(), currentActualSymbol.getName()); - assertEquals(currentExpectedSymbol.getKind(), currentActualSymbol.getKind()); - assertEquals(currentExpectedSymbol.getContainerName(), currentActualSymbol.getContainerName()); - assertEquals(currentExpectedSymbol.getLocation(), currentActualSymbol.getLocation()); - assertEquals(currentExpectedSymbol.getDeprecated(), currentActualSymbol.getDeprecated()); - } - } - - private SymbolInformation createSymbolInformation(String name, SymbolKind kind, Location location, String containerName) { - SymbolInformation temp = new SymbolInformation(name, kind, location, containerName); - return temp; - } - - private Range createRange(int startOffset, int endOffset, DOMDocument xmlDocument) { - Position start = null; + // assertRename("", "newText", edits("newText", r(0, 1, 5), + // r(0, 15, 19))); + } + + @Test + public void externalDTD() { + String xmlText = "\n" + // + ""; + String testURI = "test.dtd"; + initializeTestObjects(xmlText, testURI); + + currentLocation = createLocation(testURI, 0, 19, xmlDocument); + currentSymbolInfo = createSymbolInformation("br", SymbolKind.Property, currentLocation, ""); + expectedSymbolInfos.add(currentSymbolInfo); + + currentLocation = createLocation(testURI, 20, 40, xmlDocument); + currentSymbolInfo = createSymbolInformation("br/@%all;", SymbolKind.Key, currentLocation, ""); + expectedSymbolInfos.add(currentSymbolInfo); + + assertSymbols(expectedSymbolInfos, actualSymbolInfos); + } + + @Test + public void internalDTD() { + String xmlText = "\n" + // + " \n" + // + "]>\n" + // + "
"; + String testURI = "test.xml"; + initializeTestObjects(xmlText, testURI); + currentLocation = createLocation(testURI, 0, 63, xmlDocument); + currentSymbolInfo = createSymbolInformation("DOCTYPE:br", SymbolKind.Struct, currentLocation, ""); + expectedSymbolInfos.add(currentSymbolInfo); + + currentLocation = createLocation(testURI, 18, 37, xmlDocument); + currentSymbolInfo = createSymbolInformation("br", SymbolKind.Property, currentLocation, "DOCTYPE:br"); + expectedSymbolInfos.add(currentSymbolInfo); + + currentLocation = createLocation(testURI, 39, 60, xmlDocument); + currentSymbolInfo = createSymbolInformation("br/@%all;", SymbolKind.Key, currentLocation, "DOCTYPE:br"); + expectedSymbolInfos.add(currentSymbolInfo); + + currentLocation = createLocation(testURI, 64, 70, xmlDocument); + currentSymbolInfo = createSymbolInformation("br", SymbolKind.Field, currentLocation, ""); + expectedSymbolInfos.add(currentSymbolInfo); + + assertSymbols(expectedSymbolInfos, actualSymbolInfos); + } + // -------------------Tools------------------------------ + + private void initializeTestObjects(String xmlText) { + initializeTestObjects(xmlText, testURI); + } + + private void initializeTestObjects(String xmlText, String uri) { + xmlDocument = DOMParser.getInstance().parse(xmlText, uri, null); + actualSymbolInfos = languageService.findDocumentSymbols(xmlDocument); + expectedSymbolInfos = new ArrayList(); + } + + private void assertSymbols(List expectedSymbolList, List actualSymbolList) { + assertEquals(expectedSymbolList.size(), actualSymbolList.size()); + + SymbolInformation currentExpectedSymbol; + SymbolInformation currentActualSymbol; + + for (int i = 0; i < expectedSymbolList.size(); i++) { + currentExpectedSymbol = expectedSymbolList.get(i); + currentActualSymbol = actualSymbolList.get(i); + assertEquals("Symbol index " + i, currentExpectedSymbol.getName(), currentActualSymbol.getName()); + assertEquals("Symbol index " + i, currentExpectedSymbol.getKind(), currentActualSymbol.getKind()); + assertEquals("Symbol index " + i, currentExpectedSymbol.getContainerName(), + currentActualSymbol.getContainerName()); + assertEquals("Symbol index " + i, currentExpectedSymbol.getLocation(), currentActualSymbol.getLocation()); + assertEquals("Symbol index " + i, currentExpectedSymbol.getDeprecated(), + currentActualSymbol.getDeprecated()); + } + } + + private SymbolInformation createSymbolInformation(String name, SymbolKind kind, Location location, + String containerName) { + SymbolInformation temp = new SymbolInformation(name, kind, location, containerName); + return temp; + } + + private Range createRange(int startOffset, int endOffset, DOMDocument xmlDocument) { + Position start = null; try { - start = xmlDocument.positionAt(startOffset); + start = xmlDocument.positionAt(startOffset); } catch (BadLocationException e) { - fail("Could not create position at startOffset"); - } - Position end = null; - try { - start = xmlDocument.positionAt(startOffset); + fail("Could not create position at startOffset"); + } + Position end = null; + try { + start = xmlDocument.positionAt(startOffset); end = xmlDocument.positionAt(endOffset); } catch (BadLocationException e) { - fail("Could not create position at endOffset"); + fail("Could not create position at endOffset"); } - return new Range(start,end); - } + return new Range(start, end); + } - private Location createLocation(String uri, int startOffset, int endOffset, DOMDocument xmlDocument) { - Range range = createRange(startOffset, endOffset, xmlDocument); - return new Location(uri, range); - } + private Location createLocation(String uri, int startOffset, int endOffset, DOMDocument xmlDocument) { + Range range = createRange(startOffset, endOffset, xmlDocument); + return new Location(uri, range); + } } \ No newline at end of file