Skip to content

Commit

Permalink
Add support for textDocument/references for DTD
Browse files Browse the repository at this point in the history
Fixes #234

Signed-off-by: azerr <[email protected]>
  • Loading branch information
angelozerr committed Aug 14, 2019
1 parent 2ae6df9 commit 6455324
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@
import org.eclipse.lsp4xml.extensions.dtd.contentmodel.CMDTDContentModelProvider;
import org.eclipse.lsp4xml.extensions.dtd.participants.DTDDefinitionParticipant;
import org.eclipse.lsp4xml.extensions.dtd.participants.DTDHighlightingParticipant;
import org.eclipse.lsp4xml.extensions.dtd.participants.DTDReferenceParticipant;
import org.eclipse.lsp4xml.extensions.dtd.participants.diagnostics.DTDDiagnosticsParticipant;
import org.eclipse.lsp4xml.services.extensions.IDefinitionParticipant;
import org.eclipse.lsp4xml.services.extensions.IHighlightingParticipant;
import org.eclipse.lsp4xml.services.extensions.IReferenceParticipant;
import org.eclipse.lsp4xml.services.extensions.IXMLExtension;
import org.eclipse.lsp4xml.services.extensions.XMLExtensionsRegistry;
import org.eclipse.lsp4xml.services.extensions.diagnostics.IDiagnosticsParticipant;
Expand All @@ -32,11 +34,13 @@ public class DTDPlugin implements IXMLExtension {
private final IDiagnosticsParticipant diagnosticsParticipant;
private final IDefinitionParticipant definitionParticipant;
private IHighlightingParticipant highlightingParticipant;
private IReferenceParticipant referenceParticipant;

public DTDPlugin() {
diagnosticsParticipant = new DTDDiagnosticsParticipant();
definitionParticipant = new DTDDefinitionParticipant();
highlightingParticipant = new DTDHighlightingParticipant();
referenceParticipant = new DTDReferenceParticipant();
}

@Override
Expand All @@ -56,6 +60,8 @@ public void start(InitializeParams params, XMLExtensionsRegistry registry) {
registry.registerDefinitionParticipant(definitionParticipant);
// register highlighting participant
registry.registerHighlightingParticipant(highlightingParticipant);
// register reference participant
registry.registerReferenceParticipant(referenceParticipant);
}

@Override
Expand All @@ -66,5 +72,7 @@ public void stop(XMLExtensionsRegistry registry) {
registry.unregisterDefinitionParticipant(definitionParticipant);
// unregister highlighting participant
registry.unregisterHighlightingParticipant(highlightingParticipant);
// register reference participant
registry.unregisterReferenceParticipant(referenceParticipant);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*******************************************************************************
* Copyright (c) 2019 Red Hat Inc. and others.
* All rights reserved. This program and the accompanying materials
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* Red Hat Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.lsp4xml.extensions.dtd.participants;

import java.util.List;

import org.eclipse.lsp4j.Location;
import org.eclipse.lsp4j.Position;
import org.eclipse.lsp4j.ReferenceContext;
import org.eclipse.lsp4j.jsonrpc.CancelChecker;
import org.eclipse.lsp4xml.dom.DOMDocument;
import org.eclipse.lsp4xml.dom.DOMNode;
import org.eclipse.lsp4xml.dom.DTDElementDecl;
import org.eclipse.lsp4xml.extensions.dtd.utils.DTDUtils;
import org.eclipse.lsp4xml.services.extensions.AbstractReferenceParticipant;
import org.eclipse.lsp4xml.utils.XMLPositionUtility;

/**
* DTD reference
*
* @author Angelo ZERR
*
*/
public class DTDReferenceParticipant extends AbstractReferenceParticipant {

@Override
protected boolean match(DOMDocument document) {
return true;
}

@Override
protected void findReferences(DOMNode node, Position position, int offset, ReferenceContext context,
List<Location> locations, CancelChecker cancelChecker) {
// DTD reference works only when references is done on an <!ELEMENT name
if (!node.isDTDElementDecl()) {
return;
}
DTDElementDecl elementDecl = (DTDElementDecl) node;
if (!elementDecl.isInNameParameter(offset)) {
return;
}
DTDUtils.searchDTDOriginElementDecls(elementDecl,
(origin, target) -> locations.add(XMLPositionUtility.createLocation(origin)), cancelChecker);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*******************************************************************************
* Copyright (c) 2019 Red Hat Inc. and others.
* All rights reserved. This program and the accompanying materials
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* Red Hat Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.lsp4xml.extensions.dtd;

import static org.eclipse.lsp4xml.XMLAssert.l;
import static org.eclipse.lsp4xml.XMLAssert.r;

import org.eclipse.lsp4j.Location;
import org.eclipse.lsp4xml.XMLAssert;
import org.eclipse.lsp4xml.commons.BadLocationException;
import org.junit.Test;

/**
* DTD references tests
*
*/
public class DTDReferenceExtensionsTest {

@Test
public void referencesOnDTDElementName() throws BadLocationException {
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\r\n" + //
"<!DOCTYPE note [\r\n" + //
" <!ELEMENT no|te (to,from,heading,body, note?)>\r\n" + // <-- references on <!ELEMENT note
" <!ATTLIST note version CDATA #REQUIRED>\r\n" + //
"]>";
testReferencesFor(xml, l("test.xml", r(2, 39, 2, 43)), l("test.xml", r(3, 11, 3, 15)));
}

@Test
public void noReferencesAfterElementName() throws BadLocationException {
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\r\n" + //
"<!DOCTYPE note [\r\n" + //
" <!ELEMENT note (to,from,heading,body, note?|)>\r\n" + // <--after ?, no references
" <!ATTLIST note version CDATA #REQUIRED>\r\n" + //
"]>";
testReferencesFor(xml);
}

@Test
public void noReferencesAfterDTDAttrListName() throws BadLocationException {
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\r\n" + //
"<!DOCTYPE note [\r\n" + //
" <!ELEMENT note (to,from,heading,body, note?)>\r\n"
+ " <!ATTLIST note version CD|ATA #REQUIRED>\r\n" + // // <-- in CDATA, no references
"]>";
testReferencesFor(xml);
}

@Test
public void noReferencesOnDTDAttListName() throws BadLocationException {
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\r\n" + //
"<!DOCTYPE note [\r\n" + //
" <!ELEMENT note (to,from,heading,body, note?)>\r\n" + //
" <!ATTLIST no|te version CDATA #REQUIRED>\r\n" + // <-- no references on <!ATTLIST no|te
"]>";
testReferencesFor(xml);
}

@Test
public void noReferencesOnDTDElementChildName() throws BadLocationException {
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\r\n" + //
"<!DOCTYPE note [\r\n" + //
" <!ELEMENT note (to,from,heading,body, no|te?)>\r\n" + // <-- no references on child (... no|te?
" <!ATTLIST note version CDATA #REQUIRED>\r\n" + //
"]>";
testReferencesFor(xml);
}

private void testReferencesFor(String xml, Location... expectedItems) throws BadLocationException {
XMLAssert.testReferencesFor(xml, "test.xml", expectedItems);
}
}

0 comments on commit 6455324

Please sign in to comment.