Skip to content

Commit

Permalink
DTD Attlist symbols will show multiple ATTLIST attributes
Browse files Browse the repository at this point in the history
Fixes#265

Signed-off-by: Nikolas Komonen <[email protected]>
  • Loading branch information
NikolasKomonen authored and fbricon committed May 27, 2019
1 parent 9d78030 commit c914529
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -85,31 +86,60 @@ private void findDocumentSymbols(DOMNode node, List<DocumentSymbol> symbols, Lis
return;
}
boolean hasChildNodes = node.hasChildNodes();
List<DocumentSymbol> children = symbols;
if (!nodesToIgnore.contains(node)) {
String name = nodeToName(node);
Range selectionRange = getSymbolRange(node);
List<DocumentSymbol> 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<DOMNode> attlistDecls = node.getOwnerDocument().findDTDAttrList(elementName);
Collection<DOMNode> attlistDecls;
if(node.isDTDElementDecl()) {
DTDElementDecl elementDecl = (DTDElementDecl) node;
String elementName = elementDecl.getName();
attlistDecls = node.getOwnerDocument().findDTDAttrList(elementName);
}
else {
attlistDecls = new ArrayList<DOMNode>();
attlistDecls.add(node);
}

for (DOMNode attrDecl : attlistDecls) {
findDocumentSymbols(attrDecl, children, nodesToIgnore);
findDocumentSymbols(attrDecl, childrenSymbols, null);
if(attrDecl instanceof DTDAttlistDecl) {
DTDAttlistDecl decl = (DTDAttlistDecl) attrDecl;
List<DTDAttlistDecl> otherAttributeDecls = decl.getInternalChildren();
if(otherAttributeDecls != null) {
for (DTDAttlistDecl internalDecl : otherAttributeDecls) {
findDocumentSymbols(internalDecl, childrenSymbols, null);
}
}
}
nodesToIgnore.add(attrDecl);
}
}


}
if (!hasChildNodes) {
return;
}
final List<DocumentSymbol> childrenOfChild = children;
final List<DocumentSymbol> childrenOfChild = childrenSymbols;
node.getChildren().forEach(child -> {
try {
findDocumentSymbols(child, childrenOfChild, nodesToIgnore);
Expand Down Expand Up @@ -145,10 +175,28 @@ private void findSymbolInformations(DOMNode node, String container, List<SymbolI
});
}

private static Range getSymbolRange(DOMNode node) throws BadLocationException {
private static Range getSymbolRange(DOMNode node) throws BadLocationException{
return getSymbolRange(node, false);
}

private static Range getSymbolRange(DOMNode node, boolean useAttlistElementName) throws BadLocationException{
Position start;
Position end;
DOMDocument xmlDocument = node.getOwnerDocument();
Position start = xmlDocument.positionAt(node.getStart());
Position end = xmlDocument.positionAt(node.getEnd());

if(node.isDTDAttListDecl() && !useAttlistElementName) {
DTDAttlistDecl attlistDecl = (DTDAttlistDecl) node;
DTDDeclParameter attributeNameDecl = attlistDecl.attributeName;

if(attributeNameDecl != null) {
start = xmlDocument.positionAt(attributeNameDecl.getStart());
end = xmlDocument.positionAt(attributeNameDecl.getEnd());
return new Range(start, end);
}
}

start = xmlDocument.positionAt(node.getStart());
end = xmlDocument.positionAt(node.getEnd());
return new Range(start, end);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,44 @@ public void externalDTD() {
" %all;>";
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 =
"<!ELEMENT target EMPTY>\r\n" +
" \r\n" +
"<!ATTLIST target\r\n" +
" tid ID #IMPLIED\r\n" +
"\r\n" +
"<!ATTLIST target\r\n" +
" bee ID #IMPLIED>\r\n" +
" \r\n" +
" \r\n" +
"<!ATTLIST extension-point\r\n" +
" ep CDATA #IMPLIED\r\n" +
" ep2 CDATA #IMPLIED>\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 =
"<?xml version = \"1.0\"?>\r\n" + //
String xml = "<?xml version = \"1.0\"?>\r\n" + //
"<!DOCTYPE Folks [\r\n" + //
" <!ELEMENT Folks (Person*)>\r\n" + //
" <!ELEMENT Person (Name,Email?)>\r\n" + //
Expand All @@ -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()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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);

Expand Down

0 comments on commit c914529

Please sign in to comment.